﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HypermarketSerialPort._1_Model
{
    class CheckOutManager
    {

        private static CheckOutManager mInstance;
        private DBManager mDBManager;

        #region CheckOutManager
        //only create one instance of CheckOutManager
        public static CheckOutManager getInstance()
        {
            if (mInstance == null)
            {
                mInstance = new CheckOutManager();
            }
            return mInstance;
        }
        #endregion


        #region Constructor
        private CheckOutManager()
        {
            mDBManager = DBManager.getInstance();
        }
        #endregion

        
        #region Checkout operation
        public string OperationCheckOut(List<string> receivedInfoList, Dictionary<string, CashierRegister> cashierDict)
        {
            if (receivedInfoList.Count() == Constant.ONE)
            {
                CashierRegister cashierRegister;
                string machineID = receivedInfoList[Constant.ZERO];
                if (cashierDict.TryGetValue(machineID, out cashierRegister))
                {
                    if(cashierRegister.isTransactionStarted())
                    {
                        List<Transaction> TransactionList = cashierRegister.CheckOut();
                        if (TransactionList.Count == Constant.ZERO)
                            return Constant.ADD_TRANSACTION_FIRST;
                        return ProcessCheckOut(cashierRegister, machineID, TransactionList);
                    }
                    else
                    {
                        return Constant.START_TRANSACTION_FIRST;
                    }
                }
                else
                {
                    return Constant.LOGIN_FIRST_MSG;
                }
            }
            else
            {
                return Constant.PROGRAM_ERROR;
            }
        }

        private string ProcessCheckOut(CashierRegister cashierRegister, string machineID, List<Transaction> TransactionList)
        {
            mDBManager.AddTransactionDataRow(cashierRegister.getTransactionID(), cashierRegister.getCashierID(), machineID, cashierRegister.getTransactionDate());
            string output = Constant.TRANSACTION_ID + Constant.COLON + Constant.SPACE + cashierRegister.getTransactionID();
            double subtotal = 0.00;
            foreach (Transaction tr in TransactionList)
            {
                mDBManager.AddCheckOutItemDataRow(cashierRegister.getTransactionID(), tr.Barcode, Convert.ToDateTime(tr.BatchID),
                   Convert.ToDouble(tr.CostPirce), Convert.ToDouble(tr.SellingPrice), Convert.ToDouble(tr.Discount), tr.UnitSold);
                if (Convert.ToDouble(tr.Discount) == Constant.ZERO)
                {
                    output = output + Constant.NEWLINE + Constant.PURCHASED_ITEM_MSG + Constant.PRODUCT_ID + Constant.COLON + Constant.SPACE + tr.Barcode
                             + Constant.NEWLINE + Constant.NAME + Constant.COLON + Constant.SPACE + tr.ProductName + Constant.NEWLINE + Constant.SELLING_PRICE
                             + Constant.COLON + Constant.SPACE + Constant.DALLOR + tr.SellingPrice + Constant.NEWLINE + Constant.QUANTITY + Constant.COLON +
                             Constant.SPACE + tr.UnitSold + Constant.NEWLINE;
                    subtotal = subtotal + Convert.ToDouble(tr.SellingPrice) * Convert.ToInt16(tr.UnitSold);
                }
                else
                {
                    double newPrice = Convert.ToDouble(tr.SellingPrice) * (100 - Convert.ToDouble(tr.Discount)) / 100;
                    output = output + Constant.NEWLINE + Constant.PURCHASED_ITEM_MSG + Constant.PRODUCT_ID + Constant.COLON + Constant.SPACE + tr.Barcode + Constant.NEWLINE + Constant.NAME +
                             Constant.COLON + Constant.SPACE + tr.ProductName + Constant.NEWLINE + Constant.SELLING_PRICE + Constant.COLON + Constant.SPACE + Constant.DALLOR +
                             tr.SellingPrice + Constant.NEWLINE + Constant.DISCOUNT + Constant.COLON + Constant.SPACE + Constant.DALLOR + Math.Round(Convert.ToDecimal(newPrice), Constant.TWO)
                             + Constant.NEWLINE + Constant.QUANTITY + Constant.COLON + Constant.SPACE + tr.UnitSold + Constant.NEWLINE;
                    subtotal = subtotal + Convert.ToDouble(newPrice) * Convert.ToInt16(tr.UnitSold);
                }
            }
            subtotal = Convert.ToDouble(Math.Round(Convert.ToDecimal(subtotal), Constant.TWO));
            output = output + Constant.NEWLINE + Constant.TOTALPRICE_MSG + subtotal.ToString();
            return output;
        }
        #endregion 
    }
}
